from rest_framework import serializers
from . import models
import re
from django.core.cache import cache
from django.conf import settings

from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler


class LoginModelSerializer(serializers.ModelSerializer):
    username = serializers.CharField(write_only=True)
    password = serializers.CharField(write_only=True)

    class Meta:
        model = models.User
        fields = ('username', 'password', 'id')

    # 全局钩子
    # 校验user, 签发token, 保存到serializer
    # 用到drf-jwt认证
    def validate(self, attrs):
        user = self._many_method_login(**attrs)

        # 签发token, 并将user和token存放到序列化对象中
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        self.user = user
        self.token = token

        return attrs

    # 多方式登录
    def _many_method_login(self, **attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        if re.match(r'.*@.*', username):  # 邮箱登录
            user = models.User.objects.filter(email=username).first()
        elif re.match(r'^1[3-9][0-9]{9}$', username):  # 手机号登录
            user = models.User.objects.filter(mobile=username).first()
        else:  # 用户名登录
            user = models.User.objects.filter(username=username).first()

        if not user:
            raise serializers.ValidationError({'username': '账号有误'})

        if not user.check_password(password):
            raise serializers.ValidationError({'password': '密码错误'})

        return user


class LoginMobileSerializer(serializers.ModelSerializer):
    mobile = serializers.CharField(write_only=True)
    code = serializers.CharField(write_only=True)

    class Meta:
        model = models.User
        fields = ('mobile', 'code')

    # 局部钩子
    def validate_mobile(self, value):
        if not re.match(r'^1[3-9][0-9]{9}$', value):
            raise serializers.ValidationError('手机号格式有误')
        return value

    def validate_code(self, value):
        try:
            int(value)
            return value
        except:
            raise serializers.ValidationError('验证码格式有误')

    # 全局钩子
    # 校验user,签发token, 保存到serializer
    def validate(self, attrs):
        user = self._get_user(**attrs)

        # 签发token，并将user和token存放到序列化对象中
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        self.user = user
        self.token = token

        return attrs

    # 拿到用户对象
    def _get_user(self, **attrs):

        mobile = attrs.get('mobile')
        code = attrs.get('code')
        user = models.User.objects.filter(mobile=mobile).first()

        if not user:  # 手机号验证
            raise serializers.ValidationError({'mobile': '该手机号未注册'})

        # 拿到之前的缓存验证码
        old_code = cache.get(settings.SMS_CACHE_KEY % mobile)
        if code != old_code:
            raise serializers.ValidationError({'code': '验证码有误'})

        # 验证码只用一次，成功后就失效
        # cache.set(settings.SMS_CACHE_KEY % mobile, '0000', 0)
        return user


class RegisterModelSerializer(serializers.ModelSerializer):
    code = serializers.CharField(write_only=True)
    class Meta:
        model = models.User
        fields = ('mobile', 'password', 'code')
        extra_kwargs = {
            'mobile': {
                'max_length': 11,
                'min_length': 11
            },
            'password': {
                'min_length': 6,
                'max_length': 18
            },
        }

    # 局部钩子
    def validate_mobile(self, value):
        if not re.match(r'^1[3-9][0-9]{9}$', value):
            raise serializers.ValidationError('手机号格式有误')
        return value

    def validate_code(self, value):
        try:
            int(value)
            return value
        except:
            raise serializers.ValidationError('验证码格式有误')

    # 全局钩子
    def validate(self, attrs):
        mobile = attrs.get('mobile')
        code = attrs.pop('code')
        old_code = cache.get(settings.SMS_CACHE_KEY % mobile)
        if code != old_code:
            raise serializers.ValidationError({
                'code': '验证码有误'
            })

        attrs['username'] = mobile
        attrs['email'] = '%s@qq.com' % mobile

        return attrs

    # 创建用户
    def create(self, validated_data):
        return models.User.objects.create_user(**validated_data)


class UserInfoModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.User
        fields = (
            'id',
            'user_grade_get',
            'growth',
            'license_time',
            'is_certification',
            'money',
            'icon',
            'traffic_get',
            'em_person_get'
        )


class EmPeopleModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Emergency
        fields = ('em_name', 'mobile', 'user')


class QuestionModelSerializer(serializers.ModelSerializer):
    class Meta:
        model =models.Question
        fields = '__all__'

class ComplainModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Complain
        fields = '__all__'


class ReceiptModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Receipt
        fields = '__all__'

class TrafficListModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Traffic
        fields = '__all__'

class ReceiptListModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Receipt
        fields = '__all__'
